using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BowlingKata
{
    /// <summary>
    /// This class represents a bowling game.
    /// </summary>
    public class BowlingGame
    {
        private readonly List<Frame> frames;
        private Frame currentFrame;

        /// <summary>
        /// Create a new BowlingGame.
        /// </summary>
        public BowlingGame()
        {
            currentFrame = new Frame();
            frames = new List<Frame> { currentFrame };
        }

        /// <summary>
        /// Gets the total score of the game.
        /// </summary>
        public int TotalScore
        {
            get { return frames.Take(10).Sum(f => f.TotalScore); }
        }

        private bool GameEnded
        {
            get { return frames.Count >= 10 && frames[9].IsTotalScoreValid; }
        }

        /// <summary>
        /// Shot a certain number of pins.
        /// </summary>
        /// <param name="pins">The number of rolled pins.</param>
        public void Shot(int pins)
        {
            if (GameEnded)
            {
                throw new BowlingGameException("The game is ended.");
            }

            if (currentFrame.IsComplete)
            {
                currentFrame.NextFrame = frames.Count == 9 ? new TenthFrame() : new Frame();
                currentFrame = currentFrame.NextFrame;

                frames.Add(currentFrame);
            }

            if (pins < 0 || pins > 10 - currentFrame.Score)
            {
                throw new ArgumentOutOfRangeException();
            }

            currentFrame.Shot(pins);
        }

        /// <summary>
        /// Return the entire status of the game as a string.
        /// </summary>
        public override string ToString()
        {
            var sb = new StringBuilder();

            sb.Append(string.Join(" ", frames.Take(10)));

            for (int i = 0; i < 10 - frames.Count; ++i)
            {
                sb.Append(" --");               
            }
            
            return sb.ToString();
        }
    }
}